﻿namespace Pibby.Core.IO
{
	using System;
	using System.IO;

	using invrt;

	public class FileSystemFolder : IFolder
	{
		private DirectoryInfo Folder { get; set; }

		public bool AutoCreate { get; set; }

		public FileSystemFolder()
		{
			this.AutoCreate = false;
		}

		public FileSystemFolder(string path)
		{
			this.AutoCreate = false;
			this.Path = path;
		}

		public FileSystemFolder(Environment.SpecialFolder folder)
		{
			this.Path = Environment.GetFolderPath(folder);
		}

		public string Name
		{
			get { return this.Folder.Name; }
		}

		public string Path
		{
			get { return this.Folder.FullName; }
			set
			{
				if (this.Folder == null)
				{
					this.Folder = new DirectoryInfo(value);
				}
				else if (value != this.Folder.FullName)
				{
					this.Folder = new DirectoryInfo(value);
				}

				if (this.AutoCreate)
				{
					this.CreateFolder();
				}
			}
		}

		public IFolderCollection GetSubfolders()
		{
			Contract.EnsureIsNotNull(this.Folder, "Folder does not have a path set");

			IFolderCollection folders = new IFolderCollection();

			foreach (DirectoryInfo subDir in this.Folder.GetDirectories())
			{
				folders.Add(new FileSystemFolder(subDir.FullName));
			}

			return folders;
		}

		public IFileCollection GetFiles()
		{
			Contract.EnsureIsNotNull(this.Folder, "Folder does not have a path set");

			IFileCollection files = new IFileCollection();

			if (this.Exists)
			{
				foreach (FileInfo file in this.Folder.GetFiles())
				{
					files.Add(new FileSystemFile(file.FullName));
				}
			}

			return files;
		}

		public IFileCollection GetFiles(string searchPattern)
		{
			Contract.EnsureIsNotNull(this.Folder, "Folder does not have a path set");

			IFileCollection files = new IFileCollection();

			if (this.Exists)
			{
				foreach (FileInfo file in this.Folder.GetFiles(searchPattern))
				{
					files.Add(new FileSystemFile(file.FullName));
				}
			}

			return files;
		}

		public IFolder Append(string subfolder)
		{
			if (string.IsNullOrEmpty(subfolder))
				throw new ArgumentNullException("subfolder", "Subfolder cannot be blank");

			string newPath = System.IO.Path.Combine(this.Path, subfolder);

			FileSystemFolder folder = new FileSystemFolder(newPath);

			folder.AutoCreate = this.AutoCreate;

			return folder;
		}

		private void CreateFolder()
		{
			if (this.Folder != null && !this.Folder.Exists)
			{
				System.IO.Directory.CreateDirectory(this.Folder.FullName);
			}
		}

		public string Root
		{
			get
			{
				return System.IO.Path.GetPathRoot(this.Path);
			}
		}

		public string PathToFile(string file)
		{
			return System.IO.Path.Combine(this.Path, file);
		}

		public IFile ToFile(string file)
		{
			return new FileSystemFile(file);
		}

		public IFolder Parent
		{
			get
			{
				string newPath = System.IO.Path.Combine(this.Path, "..");

				FileSystemFolder folder = new FileSystemFolder(newPath);

				folder.AutoCreate = this.AutoCreate;

				return folder;
			}
		}

		public bool Exists
		{
			get { return Directory.Exists(this.Path); }
		}

		public void Create()
		{
			this.CreateFolder();
		}

		public void Delete()
		{
			IRecycleFiles recycleBin = InversionOfController.Factory.CreateTypeOf<IRecycleFiles>();

			recycleBin.Recycle(this.Path);
		}
	}

}
